<script lang="ts">
export default {
  name: "VMusic"
}
</script>
<script setup lang="ts">
import { computed, onMounted, ref, toRefs, watch } from "vue";
const audioRef = ref<HTMLAudioElement>();
const progressRef = ref('')
const progresscontainerRef = ref('')
interface Obj {
  title: string;
  img: string;
  src: string;
  lyric: string;
}
interface AudioProps {
  musicList?: Array<Obj>[] | undefined;
  diskHW?: string;
  progressColor?: string;
  lyricColor?: string;
  lyricSize?: string;
  offsetY?: Number;
  darkTheme?: Boolean;
}
const props = withDefaults(defineProps<AudioProps>(), {
  musicList: undefined,
  diskHW: '120px',
  lyricSize: '14px',
  lyricColor: '#1890ff',
  offsetY: 25,
  progressColor: '#1890ff',
  darkTheme: false,
})
const { musicList, offsetY } = toRefs(props);
// 默认从第一首开始
let songIndex = ref(0);
let currentLyc = ref(0);
const lyricList = ref([]);
const lycStyle = ref({});
//正在播放的音乐
const playSongSrc = computed(() => {
  return musicList.value ? musicList.value[songIndex.value] : {}
});
const paused = ref(false);
//获取歌词
const getLyric = () => {
  let result = playSongSrc.value.lyric;
  if (result) {
    let lyricData = [];
    result.split(/[\n]/)
      .forEach(item => {
        let temp = item.split(/\[(.+?)\]/)
        lyricData.push(
          {
            time: temp[1],
            lyc: temp[2]
          })
      })
    lyricData = lyricData.filter(v => v['lyc'])
    lyricList.value = lyricData;
  } else {
    audioRef.value ? audioRef.value.currentTime = 0 : null;
    currentLyc.value = 0;
    lycStyle.value = {
      transform: `translateY(-0px)`,
    }
    lyricList.value = []
    lyricList.value.push(
      {
        time: '00:01:00',
        lyc: playSongSrc.value.title
      })
  }

}
getLyric();

const timeUpdate = () => {
  if (playSongSrc.value.lyric) {
    const currentDate = getTime(audioRef.value.currentTime);
    for (let i = 0; i < lyricList.value.length; i++) {
      if (lyricList.value[i + 1] && currentDate < lyricList.value[i + 1].time && currentDate > lyricList.value[i].time) {
        currentLyc.value = i;
        lycStyle.value = {
          transform: `translateY(-${offsetY.value * i + 1}px)`,
        }
      }
    }
  }
}

// 秒转换-分:秒的格式
const getTime = time => {
  if (time) {
    const minutes = Math.floor(time / 60);
    const remainingSeconds = time % 60;
    const formattedMinutes = String(minutes).padStart(2, '0');
    const formattedSeconds = remainingSeconds.toFixed(2).replace('.', ':').padStart(5, '0');
    return `${formattedMinutes}:${formattedSeconds}`;
  } else {
    return "00:00";
  }
};
//监听
watch(playSongSrc, function (value, oldvalue) {
  try {
    audioRef.value.src = value?.src;
    getLyric();
    audioRef.value?.play();
    paused.value = true;
  } catch (e) {
    console.log(e)
  }

},)

onMounted(() => {
  try {
    audioRef.value.src = playSongSrc.value?.src;
    // 播放中添加时间变化监听
    audioRef.value.addEventListener("timeupdate", () => {
      Timeupdate();
    });
    // 当前音乐播放完毕监听
    audioRef.value.addEventListener("ended", () => {
      playEnded();
    })
    audioRef.value.addEventListener('error', function () {
      console.warn('音频文件加载失败');
      return;
    });
  } catch (e) {
    console.log(e)
  }

})
const playSong = (isplay) => {
  paused.value = audioRef.value.paused;
  paused.value ? audioRef.value?.play() : audioRef.value?.pause();
}
const switchSong = (isNext) => {
  paused.value = audioRef.value.paused;
  let number = songIndex.value;
  if (musicList.value) {
    songIndex.value == musicList.value.length - 1 ? songIndex.value = 0 : isNext ? songIndex.value++ : number == 0 ? songIndex.value = musicList.value.length - 1 : songIndex.value--;
  }
}
const Timeupdate = () => {
  updateProgress()
  timeUpdate()
}
const playEnded = () => {
  switchSong(true)
}
const updateProgress = () => {
  const {
    duration,
    currentTime
  } = audioRef.value;
  const progressPercent = (currentTime / duration) * 100;
  progressRef.value.style.width = `${progressPercent}%`
}
const setProgress = (clickX, width) => {
  const duration = audioRef.value.duration
  audioRef.value.currentTime = (clickX / width) * duration
}
const setProgressBtn = (e) => {
  const width = progresscontainerRef.value.clientWidth;
  const clickX = e.offsetX;
  setProgress(clickX, width)
}
</script>
<template>
  <div style="height: 100%;width: 100%;  display: flex;
  flex-direction: column;">
    <audio ref='audioRef'></audio>
    <div class='player'>
      <div class="player_disk">
        <div class="disk_img" :style="{ backgroundImage: `url(${playSongSrc.img})`, opacity: darkTheme ? 0.8 : 1 }">
        </div>
        <div class="control-style">
          <div class="control_btn " @click="switchSong(false)">
            <span class="play-btn">
              <slot name="last"></slot>
            </span>
          </div>
          <div class="control_btn" @click="playSong(!paused)">
            <span class="play-btn">
              <div v-show="paused">
                <slot name="pause"></slot>
              </div>
              <div v-show="!paused">
                <slot name="play"></slot>
              </div>
            </span>
          </div>
          <div class="control_btn " @click="switchSong(true)">
            <span class="play-btn">
              <slot name="next"></slot>
            </span>
          </div>
        </div>
      </div>
      <div className="player_control">
        <div class="lyricBox">
          <div :style="{ ...lycStyle, color: darkTheme ? '#bbb8b8' : '#212020', fontSize: lyricSize }" class="lyricStyle">
            <p v-for="(item, index) in lyricList" key={index}
              :style="{ color: currentLyc == index ? lyricColor : '', opacity: !darkTheme ? 1 : 0.6 }">{{ item.lyc }}</p>
          </div>
          <div className="progress-container" ref='progresscontainerRef' :style="{ opacity: !darkTheme ? 1 : 0.6 }"
            @click="(e) => { setProgressBtn(e) }">
            <div ref='progressRef' class="progress" id="progress" :style="{ 'backgroundColor': progressColor }"></div>
          </div>
        </div>

      </div>
    </div>
  </div>

</template>

<style>
.player {
  display: flex;
  height: 100%;
}

.player_disk {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.control-style {
  flex: 1;
  display: flex;
  text-align: center;
  padding-top: 10px;
}

.control_btn {
  flex: 1;
}

.player_control {
  flex: 2.2;
  margin-left: 10px;
}

.disk_img {
  text-align: center;
  width: 100%;
  height: 100%;
  border-radius: 50%; /* 正圆 */
  background-size: cover; /* 图片等比例放大填充整个容器（可能裁剪） */
  background-position: center; /* 图片居中显示 */
  background-repeat: no-repeat; /* 防止平铺 */

}

.lyricStyle {
  position: absolute;
  left: 0;
  right: 0;
  transition: all 0.3s;

}

.lyricStyle p {
  margin: 7px 0px;
}

.lyricBox {
  height: 100%;
  overflow: hidden;
  position: relative;
  text-align: center;
  padding-bottom: 10px;
}

.control {
  display: flex;
}

.progress {
  height: 100%;
  width: 0%;
  transition: width 0.2s linear;
  border-radius: 5px;
}

.progress-container {
  width: 100%;
  background-color: #000000;
  height: 3px;
  position: absolute;
  bottom: 0px;
  cursor: pointer;
  border-radius: 5px;
}

.lyricStyle p {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>
